/**
 * Sample Skeleton for "SalaryDisplayAttendance.fxml" Controller Class
 * You can copy and paste this code into your favorite IDE
 **/

package com.pentofab.payrollmanagement.ui.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextField;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;
import javafx.util.Callback;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.AttendanceDao;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.LeaveDAO;
import com.pentofab.payrollmanagement.dao.SalaryDAO;
import com.pentofab.payrollmanagement.dao.model.AttendanceLeaveDetail;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Holiday;
import com.pentofab.payrollmanagement.dao.model.SalaryStracture;
import com.pentofab.payrollmanagement.dao.model.Units;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.utilities.Constants;
import com.pentofab.payrollmanagement.utilities.CustomTableConstants;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;


public class SalaryDisplaySalaryStractureControler extends AbstractUIController implements FormValidator,
     Initializable {
	@FXML
	TextField importFileLoc;
	private EmployeeDao employeeDao =  PayrollApplicationFactory.getEmployeeMgmt();
    @FXML
    private GridPane grid;
    @FXML
    private TableView<ObservableList<StringProperty>> tableView;
    private TableColumn<AttendanceLeaveDetail, String>[] tableColmns = null;
    
    private Company company;
    private UserAccounts userAccounts;
    
    SalaryDAO salaryDAO =PayrollApplicationFactory.getSalaryDAO();
    
    public void add() {
    	
    	PayrollApplicationFactory.getMainController().showScreen(MainController.SalaryStracture, true, company,userAccounts);
    	refreshUI();
    }

    private void populateTable(final ArrayList<String> salaryStractList) {
    	
    	    System.out.println("====================== entering populateTable in =================================");
    	    System.out.println("salaryStractList : "+salaryStractList);
    	    
    	    final String header =" Emp ID,Unit ,Name,Company,Department,Category,Hours , Gross , Basic , "
    	    		+ "HRA , Conveyance , Spl Allow (CCA), Medic All,Others ,PF PFReuired,Exclude Base,Voluntary,Emp Comt,Empl Cont,"
    	    		+ "PF Num,Esi Req,ESI Num,Bank Code,Acc NO,EL,CL,SL  ";
    	    Task<Void> task = new Task<Void>() {
    	      @Override
    	      protected Void call() throws Exception {
    	        if (true) {
    	          final String[] headerValues = header.split(",");
    	          Platform.runLater(new Runnable() {
    	            @Override
    	            public void run() {
    	              for (int column = 0; column < headerValues.length; column++) {
    	            	  tableView.getColumns().add(
    	                    createColumn(column, headerValues[column].trim()));
    	              }
    	            }
    	          });
    	        }

    	        Iterator<String> salaryStrListIter  = salaryStractList.iterator();
    	        while (salaryStrListIter.hasNext()) {
    	        	
    	          final String[] dataValues = salaryStrListIter.next().split(",");
    	          Platform.runLater(new Runnable() {
    	            @Override
    	            public void run() {
    	              // Add additional columns if necessary:
    	              for (int columnIndex = tableView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
    	            	  tableView.getColumns().add(createColumn(columnIndex, ""));
    	              }
    	              // Add data to table:
    	              ObservableList<StringProperty> data = FXCollections.observableArrayList();
    	              for (String value : dataValues) {
    	                data.add(new SimpleStringProperty(value));
    	              }
    	              tableView.getItems().add(data);
    	            }
    	          });
    	        }
    	       return null; 
    	      }
    	    };
    	    Thread thread = new Thread(task);
    	    thread.setDaemon(true);
    	    thread.start();
    	    thread.run();
    	    
    	    System.out.println("====================== entering populateTable out =================================");
    	  }

    private TableColumn<ObservableList<StringProperty>, String> createColumn(
    	      final int columnIndex, String columnTitle) {
    	    TableColumn<ObservableList<StringProperty>, String> column = new TableColumn<ObservableList<StringProperty>, String>();
    	    String title;
    	    if (columnTitle == null || columnTitle.trim().length() == 0) {
    	      title = "Column " + (columnIndex + 1);
    	    } else {
    	      title = columnTitle;
    	    }
    	    column.setText(title);
    	    column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<StringProperty>, String>, ObservableValue<String>>() {
    	          @Override
    	          public ObservableValue<String> call(
    	              CellDataFeatures<ObservableList<StringProperty>, String> cellDataFeatures) {
    	            ObservableList<StringProperty> values = cellDataFeatures.getValue();
    	            if (columnIndex >= values.size()) {
    	              return new SimpleStringProperty("");
    	            } else {
    	              return cellDataFeatures.getValue().get(columnIndex);
    	            }
    	          }
    	        });
    	    
    	    if(columnIndex >3){
    	    	column.setSortable(false);
    	    }
    	    column.setEditable(false);
    	    column.resizableProperty().set(false);
    	    return column;
    	  }
    
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
		
	}

    public void goBack() {

		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
	
	}
    
    public void modify() {
    	
    	if(tableView.getSelectionModel().getSelectedIndex() < 0){
    		showError("Please select a row to modify");
    		return;
    	}
    	
    	if(!showConfirmDialog("Are sure you want to modify selected row.?")){
			return;
		}
    	
    	String empId = tableView.getSelectionModel().getSelectedItem().get(0).getValue();

    	try {
			
    		SalaryStracture salStr = salaryDAO.getSalaryStractureForEmp(empId);
			
    		PayrollApplicationFactory.getMainController().showScreen(MainController.SalaryStracture, true, company,userAccounts,salStr);
			
		} catch (BusinessException e) {

			e.printStackTrace();
			showError(e.getMessage());
		}
    	
    	refreshUI();
  	
  	}
	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {
		return "";
	}

	@Override
	public Parent getView() {
		return grid;
	}

	@Override
	public String getTitle() {
		return "Salary Stracture";
	}

	@Override
	public void refreshUI(Object... args) {
		
		importFileLoc.clear();
		if (args != null && args.length > 0) {
			Company company = (Company) args[0];
			this.company = company;
			
			if(args.length > 1 && args[1] instanceof UserAccounts){
				userAccounts = (UserAccounts) args[1];
			}
		}
	
		 tableView.getItems().clear();
 	     tableView.getColumns().clear();

 	     try {
 	    	ArrayList<String> salaryStractureList = salaryDAO.getAllEmpSalaryStracture();
			populateTable(salaryStractureList);
 	     } catch (BusinessException e) {
			e.printStackTrace();
			showError(e.getMessage());
		}
		
	}
	
	public void browseImport(){

		try{
			
			String columnString = "EMPLOYEEID,GROSSSALARY,BASIC,HRA,CONVEYANCE,SPECIALALLOWANCE,MEDICALALLOWANCE,OTHERS,PFREQUIRED,"
					+ "VOLUNTARY,EXCLUDINGBASE,EMPLOYEECONT,EMPLOYEERCONT,PFNUMBER,ESIREQUIRED,ESINUMBER,EL,CL,SL,ACCOUNTNO,BANKCODE";
			FileChooser fileChooser = new FileChooser(); 
			fileChooser.setTitle("Select Salary File");

			File file = fileChooser.showOpenDialog(null);
			File destinationFile = new File(file.getAbsolutePath());
			String fileName = destinationFile.getName();
			if(file!=null && !file.isDirectory()){

				importFileLoc.setText(destinationFile.getAbsolutePath());
				if(fileName !=null && !fileName.equals(UIMessages.FileName.SAL_LIST)){
					showError("To import Salary, Please select file having name  :"+UIMessages.FileName.SAL_LIST);
					refreshUI();
					return;
				}


				FileReader fr = new FileReader(file);

				BufferedReader br = new BufferedReader(fr);

				String colnms = br.readLine();
				if(colnms == null || colnms.equals("")){
					
					showError("No data in file : "+fileName);
					refreshUI();
					br.close();
					return;
				}else if(!colnms.equals(columnString)){
					showError("Invalid column, column name should be : "+columnString);
					refreshUI();
					br.close();
					return;
				}


				String[] colArray = colnms.split(",");
				if(colArray == null || colArray.length != 21	){

					showError("Improper data in file : "+fileName+", Valid data must contain only \n"
							+ columnString);
					br.close();
					refreshUI();
					return;
				}
				br.close();

			}else{
				showInfo("Export Operation cancelled as file not selected for import.");
				refreshUI();
				return;
			}

		}catch(Exception e){
			refreshUI();
			showError("Error while importing company data.");
		}
	}

	public void importSubmit(){

		try{

			File file = new File(importFileLoc.getText().trim());
			ArrayList<HashMap<String, String>> salaryStractureInfo = new ArrayList<HashMap<String,String>>();
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			String[] clnmsArray = br.readLine().split(",");
			String dataLine = null;
			while((dataLine = br.readLine()) != null){
				System.out.println("dataLine : "+dataLine);
				String[] data = dataLine.split(",");

				HashMap<String, String> cur = new HashMap<String, String>();
				for(int i= 0;i < data.length;i++){

					cur.put(clnmsArray[i],data[i].replaceAll("'", ""));
				}
				salaryStractureInfo.add(cur);

			}

			System.out.println("salaryStractureInfo : "+salaryStractureInfo.size());
			System.out.println("salaryStractureInfo : "+salaryStractureInfo);
			Iterator<HashMap<String, String>> salStractureMapIterator = salaryStractureInfo.iterator();
			StringBuffer errorBuffer = new StringBuffer();
			while(salStractureMapIterator.hasNext()){

				HashMap<String, String > current = salStractureMapIterator.next();
				try{
					
					SalaryStracture salaryStractureToInsert = new SalaryStracture();
					
					salaryStractureToInsert.setGrossSalary(current.get("GROSSSALARY"));
					salaryStractureToInsert.setBasic(current.get("BASIC"));
					salaryStractureToInsert.setHra(current.get("HRA"));
					salaryStractureToInsert.setConveyance(current.get("CONVEYANCE"));
					salaryStractureToInsert.setSpecialAllowance(current.get("SPECIALALLOWANCE"));
					salaryStractureToInsert.setMedicalAllowance(current.get("MEDICALALLOWANCE"));
					salaryStractureToInsert.setOthers(current.get("OTHERS"));
					
					salaryStractureToInsert.setPfrequired(current.get("PFREQUIRED").equals("1"));
					salaryStractureToInsert.setVoluntary(current.get("VOLUNTARY").equals("1"));
					salaryStractureToInsert.setExcludingBase(current.get("EXCLUDINGBASE").equals("1"));
					salaryStractureToInsert.setEmployeeCont(current.get("EMPLOYEECONT"));
					salaryStractureToInsert.setEmployeerCont(current.get("EMPLOYEERCONT"));
					salaryStractureToInsert.setPfNumber(current.get("PFNUMBER"));

					salaryStractureToInsert.setEsirequired(current.get("ESIREQUIRED").equals("1"));
					salaryStractureToInsert.setEsiNumber(current.get("ESINUMBER"));
					salaryStractureToInsert.setEl(current.get("EL"));
					salaryStractureToInsert.setCl(current.get("CL"));
					salaryStractureToInsert.setSl(current.get("SL"));
					salaryStractureToInsert.setEmployeeID(current.get("EMPLOYEEID"));
				
					salaryStractureToInsert.setAccountNo(current.get("ACCOUNTNO"));
					salaryStractureToInsert.setBankCode(current.get("BANKCODE"));
					
					
					salaryDAO.insertSalaryStracture(salaryStractureToInsert);
				}catch(Exception e){
					e.printStackTrace();
					errorBuffer.append(e.getMessage()+"\n");
				}
			}

			if(!errorBuffer.toString().equals("")){
				showError(errorBuffer.toString());
			}

			refreshUI();
			br.close();
		}catch(Exception e){
			e.printStackTrace();
			refreshUI();
			showError("Error while importing company data.");
		}

	}
}
